package cn.xiangxu.webfulx_structure.controller;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import cn.xiangxu.webfulx_structure.domain.StudentDO;
import cn.xiangxu.webfulx_structure.repository.StudentReporitory;

@RestController
@RequestMapping(value = "/stu")
@Slf4j
public class StudentController {

	private final StudentReporitory studentReporitory;

	public StudentController(StudentReporitory studentReporitory) {

		this.studentReporitory = studentReporitory;
	}

	/**
	 * 查询用户
	 * 
	 * @return
	 */
	@GetMapping(value = "/queryAll")
	public Flux<StudentDO> queryAll() {

		return studentReporitory.findAll();
	}

	/**
	 * 插叙用户【流式返回】
	 * 
	 * @return
	 */
	@GetMapping(value = "/queryAll/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
	public Flux<StudentDO> queryAllStream() {

		return studentReporitory.findAll();
	}

	/**
	 * 新增学生
	 * 
	 * @param studentDO
	 * @return
	 */
	@PostMapping(value = "/")
	public Mono<StudentDO> create(
			@RequestBody StudentDO studentDO
			) {

		if (StringUtils.isEmpty(studentDO.getId())) {
			log.info(this.getClass().getName() + " -【create】- 获取到的参数信息为：" + studentDO);
			return studentReporitory.save(studentDO);
		} else {
			log.error(this.getClass().getName() + "-【create】- 新增学生时不能传入ID信息");
			throw new RuntimeException("新增学生时不能传入ID信息");
		}
	}

	/**
	 * 创建学生【流式返回】
	 * 
	 * @param studentDO
	 * @return
	 */
	@PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
	public Mono<StudentDO> create02(
			@RequestBody StudentDO studentDO
			) {

		if (StringUtils.isEmpty(studentDO.getId())) {
			log.info(this.getClass().getName() + " -【create】- 获取到的参数信息为：" + studentDO);
			return studentReporitory.save(studentDO);
		} else {
			log.error(this.getClass().getName() + "-【create】- 新增学生时不能传入ID信息");
			throw new RuntimeException("新增学生时不能传入ID信息");
		}
	}

	/**
	 * 根据ID删除对象
	 * 
	 * @param id
	 * @return
	 */
	@DeleteMapping(value = "/{id}")
	public Mono<ResponseEntity<Void>> delete(
			@PathVariable(value = "id") String id
			) {

		log.info(id);
		if (id.chars().toArray().length == 24) {
			return studentReporitory.findById(id)
					.flatMap(
							stu -> studentReporitory.delete(stu)
									.then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK)))
					)
					.defaultIfEmpty(new ResponseEntity<Void>(HttpStatus.NOT_FOUND));
		} else {
			log.error("【delete】-参数错误");
			throw new RuntimeException("参数错误");
		}

	}

	@PutMapping(value = "/")
	public Mono<ResponseEntity> update(
			@RequestBody StudentDO studentDO
			) {

		log.info("修改数据：" + studentDO);
		return studentReporitory.findById(studentDO.getId())
				.flatMap(
						stu -> {
							log.info("数据存在");
							BeanUtils.copyProperties(studentDO, stu);
							return studentReporitory.save(stu);
						}
				)
				.map(stu -> new ResponseEntity(stu, HttpStatus.OK))
				.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
	}

	@GetMapping(value = "/queryById/{id}")
	public Mono<ResponseEntity<StudentDO>> queryById(
			@PathVariable("id") String id
			) {

		log.info("从前端获取到的ID信息为：" + id);
		return studentReporitory.findById(id)
				.map(stu -> new ResponseEntity<StudentDO>(stu, HttpStatus.OK))
				.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
	}

}
